package com.fuatnow.game.manager;

import com.fuatnow.game.entity.User;
import io.netty.channel.ChannelHandlerContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.ConcurrentHashMap;

/**
 * Created by fuatnow on 17/1/18.
 */
public class ClientConnectManager {
    private static ClientConnectManager ourInstance = new ClientConnectManager();

    public static ClientConnectManager getInstance() {
        return ourInstance;
    }

    private ClientConnectManager() {
    }
    private static final Logger logger = LoggerFactory.getLogger(ClientConnectManager.class);
    public static ConcurrentHashMap<Integer, ClientConnection> allClientMap = new ConcurrentHashMap<>();
    private static ConcurrentHashMap<Integer, Integer> userid2netidMap = new ConcurrentHashMap<>();

    public static ClientConnection getClientConnection(ChannelHandlerContext ctx) {
        Integer netId = ctx.attr(ClientConnection.NETID).get();
        if(netId == null) return  null;
        ClientConnection conn = allClientMap.get(netId);
        if(conn != null)
            return conn;
        else {
            logger.error("ClientConenction not found in allClientMap, netId: {}", netId);
        }
        return null;
    }

    public static ClientConnection getClientConnection(Integer netId) {
        ClientConnection conn = allClientMap.get(netId);
        if(conn != null)
            return conn;
        else {
            logger.error("ClientConenction not found in allClientMap, netId: {}", netId);
        }
        return null;
    }

    public static ClientConnection addClientConnection(ChannelHandlerContext c) {
        //fixme 之后重复登录需要踢掉原来的连接
        ClientConnection conn = new ClientConnection(c);

        if(ClientConnectManager.allClientMap.putIfAbsent(conn.getNetID(), conn) != null) {
            logger.error("Duplicated netid");
            return null;
        }
        return conn;
    }

    public static void removeClientConnection(ChannelHandlerContext c) {
        ClientConnection conn = getClientConnection(c);
        if(conn != null)
        {
            long netid = conn.getNetID();
            int userid = conn.getUserID();
            if (ClientConnectManager.allClientMap.remove(netid) != null) {
                unRegisterUserid(userid);
            } else {
                logger.error("NetId: {} is not exist in allClientMap", netid);
            }

            logger.info("Client disconnected, netid: {}, userid: {}", netid, userid);
        }
    }

    public static void registerUserid(User user, Integer netId) {
        if(userid2netidMap.putIfAbsent(user.getUsrID(), netId) == null) {
            ClientConnection conn = ClientConnectManager.getClientConnection(netId);
            if(conn != null) {
                conn.setUser(user);
            } else {
                logger.error("ClientConnection is null");
                return;
            }
        } else {
            logger.error("userid: {} has registered in userid2netidMap", user.getUsrID());
        }
    }

    protected static void unRegisterUserid(int userid) {
        if(ClientConnectManager.userid2netidMap.remove(userid) == null) {
            logger.error("UserId: {} is not exist in userid2netidMap", userid);
        }
    }

    public static Integer userid2netid(Integer userid) {
        Integer netid = userid2netidMap.get(userid);
        if(netid != null)
            return netid;
        else {
            logger.error("User not login, userid: {}",userid);
        }
        return null;
    }
}
